package com.zj.demo.advice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.zj.demo.anno.Encrypt;
import com.zj.demo.config.EncryptConfig;
import com.zj.demo.utils.DESUtil;
import com.zj.demo.utils.JsonUtils;
/**
 * @author 作者 zj:
 * @version 创建时间：2019年4月9日 上午10:10:37
 * 类说明
 */
public class ResponseBodyDecryptAdvice implements ResponseBodyAdvice {
	
	private Logger logger = LoggerFactory.getLogger(ResponseBodyDecryptAdvice.class);

	@Autowired
	private EncryptConfig encryptConfig;
	
	private static ThreadLocal<Boolean> encryptLocal = new ThreadLocal<Boolean>();
	
	public static void setEncryptStatus(boolean status) {
		encryptLocal.set(status);
	}

    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
    	
    	// 可以通过调用EncryptResponseBodyAdvice.setEncryptStatus(false);来动态设置不加密操作
		Boolean status = encryptLocal.get();
		if (status != null && status == false) {
			encryptLocal.remove();
			return body;
		}
		boolean encrypt = false;		
    	
    	// 对json 加密
    	String jsonBody= JsonUtils.toJson(body);
    	logger.info("====resp json===="+jsonBody);
    	if(methodParameter.getMethod().isAnnotationPresent(Encrypt.class)&& ! encryptConfig.isDebug()){
    		encrypt = true;
    	}
    	if(encrypt){
    		try {
				return DESUtil.encrypt(jsonBody,encryptConfig.getEncryptKey());
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException("响应response加密失败");
			}
    	}
        return body;
    }

}
